//
// Created by wangyihu2020 on 2022/6/9.
//

#ifndef FEM_OPENGL_TYPES_H
#define FEM_OPENGL_TYPES_H
#define DLDF
#ifdef DLDF
#include <vector>
#include <initializer_list>
typedef long long qp_int;
typedef double qp_float;
class Coord{
public:
    Coord();
    Coord(qp_float, qp_float, qp_float);
    Coord(Coord const &);
    Coord operator+(Coord const&);
    Coord operator-(Coord const&);
    qp_float operator*(Coord const&);
    Coord& operator=(Coord const&);

    Coord operator+(qp_float const *);
    Coord operator-(qp_float const *);
    qp_float operator*(qp_float const *);
    Coord& operator=(qp_float const*);

    qp_float operator[](qp_int);
private:
    qp_float m_v[3];
};

class Mat{
public:
    Mat();
    Mat(qp_int, qp_int = 0, qp_int = 0);
    Mat(Mat const &);
    Mat(Mat &&);
    virtual ~Mat();
    virtual Mat&& operator+(Mat const&);
    Mat&& operator+(qp_float const *);
    virtual Mat& operator+=(Mat const&);
    Mat& operator+=(const qp_float *);

    Mat&& operator-(Mat const&);
    Mat&& operator-(qp_float const *);
    Mat& operator-=(Mat const&);
    Mat& operator-=(qp_float const *);
    Mat&& operator*(Mat &);
    Mat&& operator*(Mat &&);
    Mat&& operator*(qp_float);
    Mat& operator*=(qp_float);

    Mat& operator=(Mat const&);
    Mat& operator=(Mat &&)  noexcept ;
    Mat& operator=(std::initializer_list<qp_float>);


//    qp_float operator*(qp_float const *);
    Mat& operator=(qp_float const*);
//
    qp_float& operator[](qp_int);
    qp_float operator[](qp_int) const;

    Mat& operator()(qp_int, qp_int = -1);

    virtual qp_int getRow() const;
    virtual qp_int getCol() const;
    qp_int getDep() const;

    void init(qp_int, qp_int = 0, qp_int = 0);
    void setRow(qp_int);
    void setCol(qp_int);

    void transpose(Mat& );
    void toArray(qp_float*);
    void print();

    void clear();

    void assignMat(qp_float*);

    void Subtracted(qp_float*);

    Mat& normalize();

    void addtoArray(qp_float*);
protected:
    qp_int m_row;
    qp_int m_col;
    qp_int m_dep;
    qp_int m_dim;
    std::vector<Mat> m_v;
    std::vector<qp_float> m_elements;
//    qp_float** m_v;
};


#else
typedef long long qp_int;
typedef double qp_float;
#endif
#endif //FEM_OPENGL_TYPES_H
